#include "CallingInstance.hpp"

#include "ProgramManager.hpp"
#include "CallingContext.hpp"
#include "SymbolTable.hpp"
#include "Memory.hpp"
#include "Instruction.hpp"

#include <iostream>
#include <iomanip>

CallingInstance::CallingInstance ( CallingContext* instanceOf ) :
    _instanceOf ( instanceOf )
{
    _localMemory = new Memory ( instanceOf->_memorySizeNeeded );
    for ( unsigned int i = 0 ; i < instanceOf->_declarationOrder.size () ; ++ i )
    {
        unsigned int memsize = getTypeSize ( instanceOf->_symbols->getTypeOf ( instanceOf->_declarationOrder [ i ] ) );
        unsigned int address = _localMemory->allocate ( memsize );
        _memoryAddressing [ instanceOf->_declarationOrder [ i ] ] = address;
    }
}

CallingInstance::~CallingInstance ()
{
}

unsigned int
CallingInstance::getAddress ( unsigned int index ) const
{
    unsigned int address = _memoryAddressing.find ( index )->second;
    return address;
}

Memory*
CallingInstance::getMemory () const
{
    return _localMemory;
}

void
CallingInstance::execute ()
{
    /* on empile ce nouvel appel */
    ProgramManager::_executionStack.push_back ( this );
    /* execution de l'appel */
    try
    {
        _instanceOf->_code->execute ();
    }
    catch ( ExpressionValue& e )
    {
        _value = e;
    }
    catch ( int& v )
    {
    }
    /* on depile l'appel */
    if ( ProgramManager::_executionStack.back () == this )
        ProgramManager::_executionStack.pop_back ();
}

ExpressionValue
CallingInstance::getValue () const
{
    return _value;
}
